// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CloudQueueMessageExtensions.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Exception for errors when handling Windows Azure Cloud Drives.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System.Web.Script.Serialization;

using Microsoft.WindowsAzure.StorageClient;

namespace AzureContrib.WindowsAzure.StorageClient
{
	/// <summary>
	/// Extensions on <see cref="CloudQueueMessage"/>
	/// </summary>
	public static class CloudQueueMessageExtensions
	{
		/// <summary>
		/// 64 * 1024 bytes  = 64KB
		/// </summary>
		public const int MaxMessageBuffer = 64 * 1024;

		private static JavaScriptSerializer JavaScriptSerializer
		{
			get
			{
				return new JavaScriptSerializer { MaxJsonLength = MaxMessageBuffer };
			}
		}

		/// <summary>
		/// Deserialize a <see cref="CloudQueueMessage"/> to an instance of the given type <typeparamref name="T"/>.
		/// </summary>
		/// <typeparam name="T">The type of oject the message is serialized from.</typeparam>
		/// <param name="cloudQueueMessage">The actual message on the queue.</param>
		/// <returns>An instance of type <typeparamref name="T"/></returns>
		public static T Payload<T>(this CloudQueueMessage cloudQueueMessage)
		{
			if (cloudQueueMessage == null)
			{
				return default(T);
			}
			
			var toDeserialize = cloudQueueMessage.AsString;
			return JavaScriptSerializer.Deserialize<T>(toDeserialize);
		}

		/// <summary>
		/// Serialize a <see cref="CloudQueueMessage"/> form an instance.
		/// </summary>
		/// <typeparam name="T">The type of instance to create a <see cref="CloudQueueMessage"/> from.</typeparam>
		/// <param name="instance">
		/// The actual message on the queue.
		/// </param>
		/// <returns>
		/// A <see cref="CloudQueueMessage"/> serialized from the data in the <paramref name="instance"/>
		/// </returns>
		public static CloudQueueMessage AsMessage<T>(this T instance)
		{
			var serialized = instance.AsString();
			return new CloudQueueMessage(serialized);
		}

		/// <summary>
		/// Serialize a <see cref="CloudQueueMessage"/> form an instance.
		/// </summary>
		/// <typeparam name="T">
		/// The type of instance to create a serialize into the body.
		/// </typeparam>
		/// <param name="cloudQueueMessage">
		/// The cloud Queue Message.
		/// </param>
		/// <param name="instance">
		/// The actual message on the queue.
		/// </param>
		public static void UpdateBody<T>(this CloudQueueMessage cloudQueueMessage, T instance)
		{
			var serialized = instance.AsString();
			if (cloudQueueMessage == null)
			{
				return;
			}

			cloudQueueMessage.SetMessageContent(serialized);
		}

		/// <summary>
		/// Serialize a <see cref="CloudQueueMessage"/> form an instance.
		/// </summary>
		/// <typeparam name="T">The type of instance to create a <see cref="CloudQueueMessage"/> from.</typeparam>
		/// <param name="instance">
		/// The actual message on the queue.
		/// </param>
		/// <returns>
		/// A <see cref="string"/> serialized from the data in the <paramref name="instance"/>
		/// </returns>
		private static string AsString<T>(this T instance)
		{
			return JavaScriptSerializer.Serialize(instance);
		}
	}
}